From: Keir Fraser Date: Sun, 23 Sep 2007 11:55:50 +0000 (+0100) Subject: vt-d: disable for old chipset steppings with incompatible page table format. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14937^2~39 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=2c1be8f16a88604b9199c7dcb04f1d07b78242a2;p=xen.git vt-d: disable for old chipset steppings with incompatible page table format. Signed-off-by: Allen Kay --- diff --git a/xen/arch/x86/hvm/vmx/vtd/dmar.c b/xen/arch/x86/hvm/vmx/vtd/dmar.c index 784af11818..44ca487bdb 100644 --- a/xen/arch/x86/hvm/vmx/vtd/dmar.c +++ b/xen/arch/x86/hvm/vmx/vtd/dmar.c @@ -489,6 +489,13 @@ acpi_parse_dmar(unsigned long phys_addr, unsigned long size) int acpi_dmar_init(void) { extern int ioapic_ack_new; + int rc; + + if (!vtd_enabled) + return -ENODEV; + + if ((rc = vtd_hw_check()) != 0) + return rc; acpi_table_parse(ACPI_DMAR, acpi_parse_dmar); @@ -499,8 +506,7 @@ int acpi_dmar_init(void) } /* Use fake-vector style of IOAPIC acknowledgement. */ - if (vtd_enabled) - ioapic_ack_new = 0; + ioapic_ack_new = 0; return 0; } diff --git a/xen/arch/x86/hvm/vmx/vtd/dmar.h b/xen/arch/x86/hvm/vmx/vtd/dmar.h index 4e66c6c88d..e6cdf62fab 100644 --- a/xen/arch/x86/hvm/vmx/vtd/dmar.h +++ b/xen/arch/x86/hvm/vmx/vtd/dmar.h @@ -87,4 +87,6 @@ struct acpi_ioapic_unit { }ioapic; }; +int vtd_hw_check(void); + #endif // _DMAR_H_ diff --git a/xen/arch/x86/hvm/vmx/vtd/utils.c b/xen/arch/x86/hvm/vmx/vtd/utils.c index 8d575292c3..fa907a544e 100644 --- a/xen/arch/x86/hvm/vmx/vtd/utils.c +++ b/xen/arch/x86/hvm/vmx/vtd/utils.c @@ -33,6 +33,37 @@ #include #include +#define VTDPREFIX "[VT-D]" +#define INTEL 0x8086 +#define SEABURG 0x4000 +#define C_STEP 2 + +int vtd_hw_check(void) +{ + u16 vendor, device; + u8 revision, stepping; + + vendor = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID); + device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); + revision = read_pci_config_byte(0, 0, 0, PCI_REVISION_ID); + stepping = revision & 0xf; + + if ( (vendor == INTEL) && (device == SEABURG) ) + { + if ( stepping < C_STEP ) + { + dprintk(XENLOG_WARNING VTDPREFIX, + "*** VT-d disabled - pre C0-step Seaburg found\n"); + dprintk(XENLOG_WARNING VTDPREFIX, + "*** vendor = %x device = %x revision = %x\n", + vendor, device, revision); + vtd_enabled = 0; + return -ENODEV; + } + } + return 0; +} + #if defined(__x86_64__) void print_iommu_regs(struct acpi_drhd_unit *drhd) {